// =============================================================
// CWork class
// ---------------------------------------
// Author : Woo-Hyun Kim
// Email : woorung@icu.ac.kr or woorung@nhncorp.com
// Date : Jul. 25, 2006
//----------------------------------------------------------------------
#include "CWork.h"
//----------------------------------------------------------------------
CWork::CWork(string &type, string &name)
{
	this->type = type;
	this->name = name;
	current_pos = 0;
}
//----------------------------------------------------------------------
CWork::~CWork()
{
}
//----------------------------------------------------------------------
int CWork::registerCommand(string &command)
{
	//commands.push_back(CShellProcess(command,1));
	commands.push_back(CShellProcess(command));

	current_pos = commands.size();
	return current_pos;
}
//----------------------------------------------------------------------
int CWork::registerCommonTaskVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		common_task_variables[attr] = val;
		
		variable++;
	}
}
//----------------------------------------------------------------------
int CWork::registerTaskVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		task_variables[attr] = val;

		variable++;
	}
}
//----------------------------------------------------------------------
int CWork::registerWorkVariables(map<string,string> &variables)
{
	map<string,string>::iterator variable = variables.begin();
	while(variable!=variables.end()) {
		string attr = variable->first;
		string val = variable->second;

		work_variables[attr] = val;

		variable++;                             
	}                                               
}
//----------------------------------------------------------------------
string &CWork::getName()
{
	return name;
}
//----------------------------------------------------------------------
string &CWork::getType()
{
	return type;
}
//----------------------------------------------------------------------
string &CWork::getParameter(char *cattr)
{
	string attr = cattr;
	return getParameter(attr);
}
//----------------------------------------------------------------------
string &CWork::getParameter(string &attr)
{
	string common_task_variable = common_task_variables[attr];
	string task_variable = task_variables[attr];
	string work_variable = work_variables[attr];

	if(work_variable!="") return work_variables[attr];
	else if(task_variable!="") return task_variables[attr];
	else return common_task_variables[attr];
}
//----------------------------------------------------------------------
int CWork::hasMoreCommands()
{
	return current_pos;
}
//----------------------------------------------------------------------
string &CWork::getNextCommand()
{
	int i = commands.size() - current_pos--;
	return commands[i].get();
}
//----------------------------------------------------------------------
void CWork::perform()
{
	if(type=="serial") { // serially execute
		vector<CShellProcess>::iterator current = commands.begin();
		while(current!=commands.end()) {
			cout << endl << endl;
			cout << "######################################################################" << endl;
			cout << "[execute] : " << current->get() << endl;
			cout << "######################################################################" << endl;
			cout << endl;

			current->start();
			if(current->waits()<0) {
				cout << current->get_pid() << " was abnromally exited" << endl;
				exit(-1);
			}
			else {
				// print out on the executing machine
			}
			current++;
		}
	}
	else if(type=="concurrent") { // concurrently execute
		vector<CShellProcess>::iterator current = commands.begin();
		while(current!=commands.end()) {
			current->start();
			current++;
		}

		// wait until commands are finished
		vector<CShellProcess>::iterator finished = commands.begin();
		while(finished!=commands.end()) {
			if(finished->waits()<0) {
				cout << finished->get_pid() << " was abnormally exited" << endl;
				exit(-1);
			}
			else {
				cout << "[execute] : " << finished->get() << endl;
				cout << endl;
				cout << "######################################################################" << endl;
				cout << " Depredicated function !!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
				cout << endl;
				cout << " the result will be printed out over stdout of the exeucting place" << endl;
				cout << "######################################################################" << endl;
			}
			finished++;
		}
	}
	else if(type=="parallel") { // execute in parallel
	}
	else if(type=="local") {
		// invoke a local method
		//CInterpreter *method = (CInterpreter *) new CIndexInterpreter(name);
		CInterpreter *method = (CInterpreter *) new CCubeInterpreter(name);
		method->invoke(common_task_variables, task_variables, work_variables);
		delete method;
	}
	else if(type=="remote") {
		cout << "[execute] : " << name << endl;
		cout << "#### not yet implemented ###" << endl;
	}
}
//----------------------------------------------------------------------
